import { createUUID } from "../utils/Utils";
import { Tick } from "./Tick";

export enum ActionStatus {
    SUCCESS = 1, 
    FAILURE = 2, 
    RUNNING = 3, 
    ERROR = 4, 
}

export enum CategoryType {
    COMPOSITE = 'composite',
    DECORATOR = 'decorator',
    ACTION = 'action',
    CONDITION = 'condition',
}

export class BaseNode {
    id: string;
    name: string;
    category: CategoryType;
    title: string;
    description: string;
    parameters: any;
    properties: any;
    child: BaseNode;
    children: BaseNode[];

    constructor(params: any) {
        params = params || {};
        this.id          = createUUID();
        this.category    = params.category;
        this.name        = name || '';
        this.title       = params.title || this.name;
        this.description = params.description || '';
        this.properties  = params.properties || {};
        this.parameters  = {};
        this.child       = null;
        this.children    = [];
    }

    
    _execute(tick: Tick) : ActionStatus {
        this._enter(tick);
        if (!tick.blackboard.get('isOpen', tick.tree.id, this.id)) {
            this._open(tick);
        }
        let status = this._tick(tick);
        if (status !== ActionStatus.RUNNING) {
            this._close(tick);
        }
        this._exit(tick);
        return status;
    }

    _enter(tick: Tick) {
        tick._enterNode(this);
        this.enter(tick);
    }

    _open(tick: Tick) {
        tick._openNode(this);
        tick.blackboard.set('isOpen', true, tick.tree.id, this.id);
        this.open(tick);
    }

    _tick(tick: Tick) : ActionStatus {
        tick._tickNode(this);
        return this.tick(tick);
    }

    _close(tick: Tick) {
        tick._closeNode(this);
        tick.blackboard.set('isOpen', false, tick.tree.id, this.id);
        this.close(tick);
    }

    _exit(tick: Tick) {
        tick._exitNode(this);
        this.exit(tick);
    }

    enter(tick: Tick) {}
    open(tick: Tick) {}
    tick(tick: Tick) : ActionStatus { return null;}
    close(tick: Tick) {}
    exit(tick: Tick) {}
}